package com.xuelang.pipeline.infrastructure.resource.repository;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xuelang.pipeline.client.common.result.PageRecord;
import com.xuelang.pipeline.client.resource.dto.ClusterQuery;
import com.xuelang.pipeline.domain.resource.Cluster;
import com.xuelang.pipeline.domain.resource.repository.ClusterRepository;
import com.xuelang.pipeline.infrastructure.resource.converter.ClusterToClusterDOConverter;
import com.xuelang.pipeline.infrastructure.resource.dataobject.ClusterDO;
import com.xuelang.pipeline.infrastructure.resource.dataobject.SpaceDO;
import com.xuelang.pipeline.infrastructure.resource.mapper.ClusterMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 集群仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class ClusterRepositoryImpl implements ClusterRepository {

    @Autowired
    ClusterMapper clusterMapper;

    @Override
    public PageRecord<Cluster> pageList(long currentPage, long pageSize, ClusterQuery clusterQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<Cluster> page = new Page<>(currentPage, pageSize);
        MPJLambdaWrapper<ClusterDO> wrapper = new MPJLambdaWrapper<ClusterDO>();
        if (clusterQuery != null) {
            wrapper.selectAll(ClusterDO.class)
                    .like(StrUtil.isNotBlank(clusterQuery.getCondition()), ClusterDO::getName, clusterQuery.getCondition())
                    .apply(StrUtil.isNotBlank(clusterQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", clusterQuery.getStartDate())
                    .apply(StrUtil.isNotBlank(clusterQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", clusterQuery.getEndDate())
                    .orderByDesc(ClusterDO::getCreateTime);
        }
        clusterMapper.selectJoinPage(page, Cluster.class, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords()
        );
    }

    @Override
    public List<Cluster> list(ClusterQuery clusterQuery) {
        MPJLambdaWrapper<ClusterDO> wrapper = new MPJLambdaWrapper<ClusterDO>();
        if (clusterQuery != null) {
            wrapper.selectAll(ClusterDO.class)
                    .like(StrUtil.isNotBlank(clusterQuery.getCondition()), ClusterDO::getName, clusterQuery.getCondition())
                    .apply(StrUtil.isNotBlank(clusterQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", clusterQuery.getStartDate())
                    .apply(StrUtil.isNotBlank(clusterQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", clusterQuery.getEndDate())
                    .orderByDesc(SpaceDO::getCreateTime);
        }
        return clusterMapper.selectJoinList(Cluster.class, wrapper);
    }


    @Override
    public Boolean save(Cluster cluster) {
        return clusterMapper.insert(ClusterToClusterDOConverter.INSTANCE.clusterToClusterDO(cluster)) == 1;
    }

    @Override
    public Boolean update(Cluster cluster) {
        return clusterMapper.update(
                ClusterToClusterDOConverter.INSTANCE.clusterToClusterDO(cluster),
                Wrappers.lambdaQuery(ClusterDO.class).eq(ClusterDO::getUuid, cluster.getUuid())) == 1;
    }

    @Override
    public Boolean delete(String clusterUuid) {
        return clusterMapper.delete(Wrappers.lambdaQuery(ClusterDO.class)
                .eq(ClusterDO::getUuid, clusterUuid)) == 1;
    }

    @Override
    public Boolean existsAlias(String clusterUuid, String clusterAlias) {
        List<ClusterDO> clusterDOS = clusterMapper.selectList(Wrappers.lambdaQuery(ClusterDO.class)
                .eq(ClusterDO::getAlias, clusterAlias));
        if (ObjectUtil.isEmpty(clusterDOS)) {
            return false;
        }
        return clusterDOS.stream().anyMatch(clusterDO -> !StringUtils.equals(clusterUuid, clusterDO.getUuid()));
    }

    @Override
    public Boolean existsName(String clusterUuid, String clusterName) {
        List<ClusterDO> clusterDOS = clusterMapper.selectList(Wrappers.lambdaQuery(ClusterDO.class)
                .eq(ClusterDO::getName, clusterName));
        if (ObjectUtil.isEmpty(clusterDOS)) {
            return false;
        }
        return clusterDOS.stream().anyMatch(clusterDO -> !StringUtils.equals(clusterUuid, clusterDO.getUuid()));
    }

    @Override
    public Boolean existsCluster(String clusterUuid) {
        return clusterMapper.exists(Wrappers.lambdaQuery(ClusterDO.class)
                .eq(ClusterDO::getUuid, clusterUuid));
    }

    @Override
    public Cluster query(String clusterUuid) {
        ClusterDO clusterDO = clusterMapper.selectOne(Wrappers.lambdaQuery(ClusterDO.class).eq(ClusterDO::getUuid, clusterUuid));
        return ClusterToClusterDOConverter.INSTANCE.clusterDOToCluster(clusterDO);
    }

}
